unit oBA;

interface

uses oPedActor, oCellularWorld, oCoordinates, sysutils, Dialogs, oPathFinding;

function BASim(paActor: TPedActor): boolean; forward;

implementation

uses
  oSimulation, oCellularMotion, oLogicalEntity;

function BASim(paActor: TPedActor): boolean;
  var CellWorld : tCellularWorld;
      x, y, gain, resGain, pedCount, resultX, resultY, barrierCount : integer;
      profit, best : real;
      destPos : tCoordinates;
      f : textfile;
begin
  // najprv ziskam CellWorld Levelu na ktorom sa pohybujem :D
  CellWorld := (paActor.MySim as tPedSimulation).World.getLevel(paActor.Pedestrian.Level).CellWorld;
  // nastavim dake hovadiny
  best := - MaxInt;
  result := False;
  with paActor.Pedestrian do begin

    //Showmessage('gT : ' + inttostr(GainTightning) + ', cT : ' + floattostr(CrowdTightning) + ', bT : ' + floattostr(barrierTightning));

    if paActor.TargetMatrix <> nil then begin
    //kukam okolite bunky
    for x := -1 to 1 do begin
      for y := -1 to 1 do begin

        if (DiagonalMoving) or (abs(x) <> abs(y)) then begin // ci sa hybem po diagonalach
          if IsIndexOK(CellWorld, CellIndex.X + x, CellIndex.Y + y) then // ak sa nepytam mimo sveta
          if IsRelevantCell(CellWorld, CellIndex.X + x, CellIndex.Y + y) then begin //ak je priechodna tak pre nu pocitam profit
            gain := paActor.TargetMatrix[CellIndex.X, CellIndex.y] - paActor.TargetMatrix[CellIndex.X + x, CellIndex.y + y];
            pedCount := GetCountOfPedestrians(CellWorld, CellIndex.X + x, CellIndex.Y + y, 1); // daj pocet chodcov v okoli tejto bunky
            barrierCount := GetCountOfBarrierCells(CellWorld, CellIndex.X + x, CellIndex.Y + y, 1); // daj pocet stien v okoli tejto bunky

            {/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////}
            {////////////////  toto je ucelovka, podla ktorej vybera najvyhodnejsiu bunku   //////////////////////////////////////////////}
            {/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////}
            {/////}  profit := (pedCount * CrowdTightning) +  (barrierCount * BarrierTightning)  + (gain * GainTightning); {//////////////}
            {/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////}

            if profit > best  then begin //ulozim profit aj poziciu ak je lepsi ako doteraz najdeny
              resultX := x;
              resultY := y;
              best := profit;
              resGain := gain;
            end;
          end;
        end;

      end;
    end;

    if (best <> - MaxInt) then begin //hybem s pandrlakom len ak sa ma kam pohnut
      //zistujem stred bunky, na ktoru sa mam pohnut, hybem sa v spojitom svete
      destPos := TCoordinates.Create;

      // funkcia ti vrati vytvorene Tcoordinates
      destPos :=  (paActor.MySim as tPedSimulation).World.getLevel(paActor.Pedestrian.Level)
      .CellWorld.getCentreOfCell(CellIndex.X + resultX, CellIndex.Y + resultY);
      (paActor.MySim as tPedSimulation).World.getLevel(paActor.Pedestrian.Level).updatePedestrian(paActor.Pedestrian, destPos);
      destPos.Free;
    end;
    end;

    //testujem ci je v cieli, ale toto je podla mna somarina, aby to robil vzdy, to by mal iba ak sa posuval
    if IsDestinationReached(paActor) then
        result := true
  end;
end;

end.

